package com.xunyin.modules.mp.service;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.profitsharing.*;
import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingReceiver;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.xunyin.api.BusinessException;
import com.xunyin.api.XunyinException;
import com.xunyin.enums.AppFromEnum;
import com.xunyin.enums.BillDetailEnum;
import com.xunyin.enums.OrderInfoEnum;
import com.xunyin.enums.PayMethodEnum;
import com.xunyin.modules.goods.service.TGoodsOrderService;
import com.xunyin.modules.mp.config.WxPayConfiguration;
import com.xunyin.modules.mtstore.domain.MtStore;
import com.xunyin.modules.mtstore.service.StoreService;
import com.xunyin.modules.recharge.domain.TRechargeOrder;
import com.xunyin.modules.recharge.service.TRechargeOrderService;
import com.xunyin.modules.shareorder.domain.TShareOrder;
import com.xunyin.modules.shareorder.service.TShareOrderService;
import com.xunyin.modules.shareorder.vo.TShareOrderVo;
import com.xunyin.utils.IpUtil;
import com.xunyin.utils.RedisUtils;
import com.xunyin.utils.ShopKeyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName 微信支付WeixinPayShareBusService
 * @Author admin
 * @Date 2022/10/30
 **/
@Service
public class WeixinPayShareBusService {
    private static final Logger log = LoggerFactory.getLogger(WeixinPayShareBusService.class);

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private TShareOrderService shareOrderService;

    @Autowired
    private StoreService storeService;

    @Autowired
    private TRechargeOrderService rechargeOrderService;

    @Autowired
    private TGoodsOrderService goodsOrderService;

    @Value("${project.tea.server}")
    private String projectTeaServer;

    @Value("${project.pay.server}")
    private String projectPayServer;

    /**
     * 统一支付入口
     *
     * @param appOrderNo 单号
     * @param from       来源
     * @param attach     备注 普通支付还是充值
     * @param body       内容
     * @return Object
     */
    public Object unifyPay(Integer storeId, String appOrderNo, String from, String attach, String body) {
        int payPrice = 0;
        String openid = "";
        //BigDecimal bigDecimal = new BigDecimal(100);

        // 预约支付订单
        if (BillDetailEnum.TYPE_3.getValue().equals(attach)) {
            TShareOrderVo orderInfo = shareOrderService.getOrderInfo(appOrderNo, null);
            // 查询订单信息
            if (ObjectUtil.isNull(orderInfo)) {
                throw new XunyinException("订单不存在");
            }
            if (orderInfo.getOrderStatus().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
                throw new XunyinException("该订单已支付");
            }
            if (orderInfo.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
                throw new XunyinException("该支付无需支付");
            }
            openid = orderInfo.getAppUserId();
            //uid = orderInfo.getUid().intValue();
            //计算分
            BigDecimal bigDecimal = new BigDecimal(100);
            payPrice = bigDecimal.multiply(orderInfo.getPayMoney()).intValue();

        // 充值
        } else if (BillDetailEnum.TYPE_1.getValue().equals(attach)) {
            LambdaQueryWrapper<TRechargeOrder> wrappers = Wrappers.<TRechargeOrder>lambdaQuery();
            wrappers.eq(TRechargeOrder::getAppOrderNo, appOrderNo);
            TRechargeOrder userRecharge = rechargeOrderService.getOne(wrappers);
            if (userRecharge == null) {
                throw new BusinessException("充值订单不存在");
            }
            if (userRecharge.getOrderStatus().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
                throw new XunyinException("该订单已支付");
            }
            openid = userRecharge.getAppUserId();
            BigDecimal bigDecimal = new BigDecimal(100);
            payPrice = bigDecimal.multiply(BigDecimal.valueOf(userRecharge.getPayMoney())).intValue();
        }

        WxPayService wxPayService = null;
        //wxPayService.getProfitSharingService().profitSharing()
        if (AppFromEnum.ROUNTINE.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WXAPP);
        } else if (AppFromEnum.APP.getValue().equals(from) || AppFromEnum.PC.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.APP);
        } else {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WECHAT);
        }

        log.info("微信支付金额计算分：{}", payPrice);
        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setOutTradeNo(appOrderNo);
        orderRequest.setTotalFee(payPrice);
        orderRequest.setSpbillCreateIp(IpUtil.getLocalIP());
        orderRequest.setNotifyUrl(this.getApiUrl() + "/api/wechatv/notify");
        orderRequest.setBody(body);
        orderRequest.setAttach(attach);
        // https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=26_3
        orderRequest.setProfitSharing("N");

        if (AppFromEnum.WEIXIN_H5.getValue().equals(from)) {
            orderRequest.setTradeType("MWEB");
        } else if (AppFromEnum.APP.getValue().equals(from)) {
            orderRequest.setTradeType("APP");
        } else if (AppFromEnum.PC.getValue().equals(from)) {
            orderRequest.setTradeType("NATIVE");
            orderRequest.setProductId(UUID.fastUUID().toString());
        } else {
            orderRequest.setTradeType("JSAPI");
            if (AppFromEnum.ROUNTINE.getValue().equals(from)) {
                orderRequest.setOpenid(openid);
            } else {
                orderRequest.setOpenid(openid);
            }
        }
        try {

            return wxPayService.createOrder(orderRequest);

        } catch (WxPayException e) {
            log.info("支付错误信息：{}", e.getMessage());
            throw new BusinessException(e.getMessage());
        }


    }

        /*    [
            {
                "type": "MERCHANT_ID",
                    "account":"190001001",
                    "amount":100,
                    "description": "分到商户"
            },
            {
                "type": "PERSONAL_OPENID",
                    "account":"86693952",
                    "amount":888,
                    "description": "分到个人"
            }
        ]*/

    // https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_3&index=4
    public void addReceiverPersonal(Integer storeId) throws WxPayException {
        ProfitSharingReceiverRequest request = new ProfitSharingReceiverRequest();
        JSONObject jsonObject = new JSONObject();
        // type: MERCHANT_ID表示商户号（mch_id或者sub_mch_id），PERSONAL_OPENID表示个人openid
        jsonObject.put("type", "PERSONAL_OPENID");
        // 类型是MERCHANT_ID时，是商户号（mch_id或者sub_mch_id）
        // 类型是PERSONAL_OPENID时，是个人openid
        jsonObject.put("account", "oZsIe0wffYx4pBjJKweWrHUMWna8");   // 个人的微信号，需要事先添加分账接收人
        jsonObject.put("relation_type", "PARTNER");
        request.setReceiver(jsonObject.toString());
        WxPayService wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WECHAT);
        wxPayService.getProfitSharingService().addReceiver(request);
    }

    public void addReceiverMerchant(Integer storeId) throws WxPayException {
        ProfitSharingReceiverRequest request = new ProfitSharingReceiverRequest();
        JSONObject jsonObject = new JSONObject();
        // type: MERCHANT_ID表示商户号（mch_id或者sub_mch_id），PERSONAL_OPENID表示个人openid
        jsonObject.put("type", "MERCHANT_ID");
        // 类型是MERCHANT_ID时，是商户号（mch_id或者sub_mch_id）
        // 类型是PERSONAL_OPENID时，是个人openid
        jsonObject.put("account", redisUtils.getY(ShopKeyUtils.getWxPayMchId()));
        // relation_type（与分账方的关系类型）
        // SERVICE_PROVIDER：服务商
        // PARTNER：合作伙伴
        // BRAND：品牌方
        jsonObject.put("relation_type", "PARTNER");
        request.setReceiver(jsonObject.toString());
        WxPayService wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WECHAT);
        wxPayService.getProfitSharingService().addReceiver(request);
    }

    public String queryProfitSharing3(TShareOrder orderInfo, String from) throws WxPayException {
        ProfitSharingQueryRequest request = new ProfitSharingQueryRequest();
        request.setOutOrderNo(orderInfo.getOrderNo());
        request.setTransactionId(orderInfo.getTransactionId());
        WxPayService wxPayService = null;
        //wxPayService.getProfitSharingService().profitSharing()
        Integer storeId = orderInfo.getStoreId();
        if (AppFromEnum.ROUNTINE.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WXAPP);
        } else if (AppFromEnum.APP.getValue().equals(from) || AppFromEnum.PC.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.APP);
        } else {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WECHAT);
        }

        ProfitSharingQueryResult result =  wxPayService.getProfitSharingService().profitSharingQuery(request);

        // wxPayService.getProfitSharingService().profitSharingReturn();

        // wxPayService.getProfitSharingService().profitSharingFinish();

        log.info("queryProfitSharing-result.getStatus:"+result.getStatus());
        log.info("queryProfitSharing-orderid={}, 查询分账结果result={}", orderInfo.getId(), JSONObject.toJSONString(result));
        return result.getStatus();
    }

    public String createProfitSharing3(TShareOrder orderInfo, String from) throws WxPayException {
        com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingRequest request = new com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingRequest();
        request.setOutOrderNo(orderInfo.getOrderNo());
        request.setTransactionId(orderInfo.getTransactionId());
        // 实际支付金额，查询商户id对应给平台商户方的分账比例
        // 计算分
        BigDecimal bigDecimal = new BigDecimal(100);
        long payPrice = bigDecimal.multiply(orderInfo.getPayMoney()).longValue();
        List<ProfitSharingReceiver> receivers = new ArrayList<>();
        ProfitSharingReceiver profitSharingReceiver = new ProfitSharingReceiver();
        MtStore mtStore = storeService.queryStoreById(orderInfo.getStoreId());
        profitSharingReceiver.setAccount(mtStore.getWxMchId());
        profitSharingReceiver.setAmount(payPrice);
        profitSharingReceiver.setType("MERCHANT_ID");
        profitSharingReceiver.setDescription("分账解冻");
        receivers.add(profitSharingReceiver);
        request.setReceivers(receivers);
        request.setUnfreezeUnsplit(false);
        WxPayService wxPayService = null;
        //wxPayService.getProfitSharingService().profitSharing()
        Integer storeId = orderInfo.getStoreId();
        if (AppFromEnum.ROUNTINE.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WXAPP);
        } else if (AppFromEnum.APP.getValue().equals(from) || AppFromEnum.PC.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.APP);
        } else {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WECHAT);
        }

        com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingResult result =  wxPayService.getProfitSharingV3Service().profitSharing(request);

        // wxPayService.getProfitSharingService().profitSharingReturn();

        // wxPayService.getProfitSharingService().profitSharingFinish();


        log.info("createProfitSharing3-result.getState:"+result.getState());
        log.info("createProfitSharing3-orderid={}, 分账结果result={}", orderInfo.getId(), JSONObject.toJSONString(result));
        return result.getState();
    }

    public String queryProfitSharing(TShareOrder orderInfo, String from) throws WxPayException {
        ProfitSharingQueryRequest request = new ProfitSharingQueryRequest();
        request.setOutOrderNo(orderInfo.getOrderNo());
        request.setTransactionId(orderInfo.getTransactionId());
        WxPayService wxPayService = null;
        //wxPayService.getProfitSharingService().profitSharing()
        Integer storeId = orderInfo.getStoreId();
        if (AppFromEnum.ROUNTINE.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WXAPP);
        } else if (AppFromEnum.APP.getValue().equals(from) || AppFromEnum.PC.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.APP);
        } else {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WECHAT);
        }

        ProfitSharingQueryResult result =  wxPayService.getProfitSharingService().profitSharingQuery(request);

        // wxPayService.getProfitSharingService().profitSharingReturn();

        // wxPayService.getProfitSharingService().profitSharingFinish();

        log.info("queryProfitSharing-result.getStatus:"+result.getStatus());
        log.info("queryProfitSharing-orderid={}, 查询分账结果result={}", orderInfo.getId(), JSONObject.toJSONString(result));
        return result.getStatus();
    }

    public String createProfitSharing(TShareOrder orderInfo, String from,Integer orderCharge) throws WxPayException {
        ProfitSharingRequest request = new ProfitSharingRequest();
        //10102024020223345623188
        // 4200002107202402026123101623
        //request.setOutOrderNo("10102024020223345623188");
        //request.setTransactionId("4200002107202402026123101623");
        request.setOutOrderNo(orderInfo.getOrderNo());
        request.setTransactionId(orderInfo.getTransactionId());

        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "MERCHANT_ID");
        jsonObject.put("account", redisUtils.getY(ShopKeyUtils.getWxPayMchId()));

        // 实际支付金额，查询商户id对应给平台商户方的分账比例
        // 计算分
        BigDecimal bigDecimal = new BigDecimal(100);
        int payPrice = bigDecimal.multiply(orderInfo.getPayMoney()).intValue();
        //分账百分之mtStore.getOrderCharge()
        //profitSharingReceiver.setAmount(money * 100 / 5);
        jsonObject.put("amount", payPrice / orderCharge);    // 分账金额单位是分，注意不要超过最大分账比例
        jsonObject.put("description", "商户订单给平台商户的抽点");
        jsonArray.add(jsonObject);
//        JSONArray jsonArray = new JSONArray();
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("type", "PERSONAL_OPENID");
//        MtStore mtStore = storeService.queryStoreById(orderInfo.getStoreId());
//        jsonObject.put("account", mtStore.getWxMchId());
//
//        // 实际支付金额，查询商户id对应给平台商户方的分账比例
//        // 计算分
//        BigDecimal bigDecimal = new BigDecimal(100);
//        int payPrice = bigDecimal.multiply(orderInfo.getPayMoney()).intValue();
//        //分账百分之mtStore.getOrderCharge()
//        //profitSharingReceiver.setAmount(money * 100 / 5);
//        jsonObject.put("amount", payPrice / orderCharge);    // 分账金额单位是分，注意不要超过最大分账比例
//        jsonObject.put("description", "分到个人");
//        jsonArray.add(jsonObject);
        // jsonArray.put(jsonObject);

        //jsConfig.put("nonceStr", wxPayMpOrderResult.getNonceStr());
        //jsConfig.put("paySign", wxPayMpOrderResult.getPaySign());

        //jsConfig.put("package", wxPayMpOrderResult.getPackageValue());
        //jsConfig.put("signType", wxPayMpOrderResult.getSignType());
        request.setReceivers(jsonArray.toString());

        WxPayService wxPayService = null;
        //wxPayService.getProfitSharingService().profitSharing()
        Integer storeId = orderInfo.getStoreId();
        if (AppFromEnum.ROUNTINE.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WXAPP);
        } else if (AppFromEnum.APP.getValue().equals(from) || AppFromEnum.PC.getValue().equals(from)) {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.APP);
        } else {
            wxPayService = WxPayConfiguration.getPayService(storeId, PayMethodEnum.WECHAT);
        }

        ProfitSharingResult result =  wxPayService.getProfitSharingService().profitSharing(request);

        // wxPayService.getProfitSharingService().profitSharingReturn();

        // wxPayService.getProfitSharingService().profitSharingFinish();


        log.info("createProfitSharing-result.getStatus:"+result.getStatus());
        log.info("createProfitSharing-orderid={}, 分账结果result={}", orderInfo.getId(), JSONObject.toJSONString(result));
        return result.getStatus();
    }

    /**
     * 返回H5 url
     *
     * @return url
     */
    private String getApiUrl() {
        String apiUrl = redisUtils.getY(ShopKeyUtils.getApiUrl());
        if (StrUtil.isBlank(apiUrl)) {
            throw new XunyinException("请配置移动端api地址");
        }
        return apiUrl;
    }


}
